home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / readpix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  24.7 KB  |  903 lines

  1. /* $Id: readpix.c,v 1.7 1997/02/03 20:31:15 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: readpix.c,v $
  26.  * Revision 1.7  1997/02/03 20:31:15  brianp
  27.  * added a few DEFARRAY macros for BeOS
  28.  *
  29.  * Revision 1.6  1997/01/16 19:24:05  brianp
  30.  * replaced a few abort()'s with gl_error() calls
  31.  *
  32.  * Revision 1.5  1996/12/20 20:28:04  brianp
  33.  * use DEF/UNDEFARRAY() macros in read_color_pixels() for Mac compilers
  34.  *
  35.  * Revision 1.4  1996/11/01 03:20:47  brianp
  36.  * reading GL_LUMINANCE pixels weren't clamped
  37.  *
  38.  * Revision 1.3  1996/09/27 01:29:47  brianp
  39.  * added missing default cases to switches
  40.  *
  41.  * Revision 1.2  1996/09/15 14:18:37  brianp
  42.  * now use GLframebuffer and GLvisual
  43.  *
  44.  * Revision 1.1  1996/09/13 01:38:16  brianp
  45.  * Initial revision
  46.  *
  47.  */
  48.  
  49.  
  50. #include <math.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include "alphabuf.h"
  54. #include "context.h"
  55. #include "depth.h"
  56. #include "feedback.h"
  57. #include "dlist.h"
  58. #include "macros.h"
  59. #include "image.h"
  60. #include "readpix.h"
  61. #include "span.h"
  62. #include "stencil.h"
  63. #include "types.h"
  64.  
  65.  
  66.  
  67.  
  68.  
  69. /*
  70.  * Read a block of color index pixels.
  71.  */
  72. static void read_index_pixels( GLcontext *ctx,
  73.                                GLint x, GLint y,
  74.                    GLsizei width, GLsizei height,
  75.                    GLenum type, GLvoid *pixels )
  76. {
  77.    GLint i, j;
  78.    GLuint a, s, k, l, start;
  79.  
  80.    /* error checking */
  81.    if (ctx->Visual->RGBAflag) {
  82.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  83.       return;
  84.    }
  85.  
  86.    /* Size of each component */
  87.    s = gl_sizeof_type( type );
  88.    if (s<=0) {
  89.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  90.       return;
  91.    }
  92.  
  93.    /* Compute packing parameters */
  94.    a = ctx->Pack.Alignment;
  95.    if (ctx->Pack.RowLength>0) {
  96.       l = ctx->Pack.RowLength;
  97.    }
  98.    else {
  99.       l = width;
  100.    }
  101.    /* k = offset between rows in components */
  102.    if (s>=a) {
  103.       k = l;
  104.    }
  105.    else {
  106.       k = a/s * CEILING( s*l, a );
  107.    }
  108.  
  109.    /* offset to first component returned */
  110.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  111.  
  112.    /* process image row by row */
  113.    for (j=0;j<height;j++,y++) {
  114.       GLuint index[MAX_WIDTH];
  115.       (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, index );
  116.  
  117.       if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  118.      GLuint s;
  119.      if (ctx->Pixel.IndexShift<0) {
  120.         /* right shift */
  121.         s = -ctx->Pixel.IndexShift;
  122.         for (i=0;i<width;i++) {
  123.            index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
  124.         }
  125.      }
  126.      else {
  127.         /* left shift */
  128.         s = ctx->Pixel.IndexShift;
  129.         for (i=0;i<width;i++) {
  130.            index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
  131.         }
  132.      }
  133.       }
  134.  
  135.       if (ctx->Pixel.MapColorFlag) {
  136.      for (i=0;i<width;i++) {
  137.         index[i] = ctx->Pixel.MapItoI[ index[i] ];
  138.      }
  139.       }
  140.  
  141.       switch (type) {
  142.      case GL_UNSIGNED_BYTE:
  143.         {
  144.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  145.            for (i=0;i<width;i++) {
  146.           *dst++ = (GLubyte) index[i];
  147.            }
  148.         }
  149.         break;
  150.      case GL_BYTE:
  151.         {
  152.            GLbyte *dst = (GLbyte *) pixels + start + j * k;
  153.            for (i=0;i<width;i++) {
  154.           *dst++ = (GLbyte) index[i];
  155.            }
  156.         }
  157.         break;
  158.      case GL_UNSIGNED_SHORT:
  159.         {
  160.            GLushort *dst = (GLushort *) pixels + start + j * k;
  161.            for (i=0;i<width;i++) {
  162.           *dst++ = (GLushort) index[i];
  163.            }
  164.            if (ctx->Pack.SwapBytes) {
  165.           gl_swap2( (GLushort *) pixels + start + j * k, width );
  166.            }
  167.         }
  168.         break;
  169.      case GL_SHORT:
  170.         {
  171.            GLshort *dst = (GLshort *) pixels + start + j * k;
  172.            for (i=0;i<width;i++) {
  173.           *dst++ = (GLshort) index[i];
  174.            }
  175.            if (ctx->Pack.SwapBytes) {
  176.           gl_swap2( (GLushort *) pixels + start + j * k, width );
  177.            }
  178.         }
  179.         break;
  180.      case GL_UNSIGNED_INT:
  181.         {
  182.            GLuint *dst = (GLuint *) pixels + start + j * k;
  183.            for (i=0;i<width;i++) {
  184.           *dst++ = (GLuint) index[i];
  185.            }
  186.            if (ctx->Pack.SwapBytes) {
  187.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  188.            }
  189.         }
  190.         break;
  191.      case GL_INT:
  192.         {
  193.            GLint *dst = (GLint *) pixels + start + j * k;
  194.            for (i=0;i<width;i++) {
  195.           *dst++ = (GLint) index[i];
  196.            }
  197.            if (ctx->Pack.SwapBytes) {
  198.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  199.            }
  200.         }
  201.         break;
  202.      case GL_FLOAT:
  203.         {
  204.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  205.            for (i=0;i<width;i++) {
  206.           *dst++ = (GLfloat) index[i];
  207.            }
  208.            if (ctx->Pack.SwapBytes) {
  209.           gl_swap4( (GLuint *) pixels + start + j * k, width );
  210.            }
  211.         }
  212.         break;
  213.          default:
  214.             gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  215.       }
  216.    }
  217. }
  218.  
  219.  
  220.  
  221. static void read_depth_pixels( GLcontext *ctx,
  222.                                GLint x, GLint y,
  223.                    GLsizei width, GLsizei height,
  224.                    GLenum type, GLvoid *pixels )
  225. {
  226.    GLint i, j;
  227.    GLuint a, s, k, l, start;
  228.    GLboolean bias_or_scale;
  229.  
  230.    /* Error checking */
  231.    if (ctx->Visual->DepthBits<=0) {
  232.       /* No depth buffer */
  233.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  234.       return;
  235.    }
  236.  
  237.    bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
  238.  
  239.    /* Size of each component */
  240.    s = gl_sizeof_type( type );
  241.    if (s<=0) {
  242.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  243.       return;
  244.    }
  245.  
  246.    /* Compute packing parameters */
  247.    a = ctx->Pack.Alignment;
  248.    if (ctx->Pack.RowLength>0) {
  249.       l = ctx->Pack.RowLength;
  250.    }
  251.    else {
  252.       l = width;
  253.    }
  254.    /* k = offset between rows in components */
  255.    if (s>=a) {
  256.       k = l;
  257.    }
  258.    else {
  259.       k = a/s * CEILING( s*l, a );
  260.    }
  261.  
  262.    /* offset to first component returned */
  263.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  264.  
  265.    if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
  266.        && !bias_or_scale && !ctx->Pack.SwapBytes) {
  267.       /* Special case: directly read 16-bit unsigned depth values. */
  268.       for (j=0;j<height;j++,y++) {
  269.          GLushort *dst = (GLushort *) pixels + start + j * k;
  270.          (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  271.       }
  272.    }
  273.    else if (type==GL_UNSIGNED_INT && sizeof(GLdepth)==sizeof(GLuint)
  274.             && !bias_or_scale && !ctx->Pack.SwapBytes) {
  275.       /* Special case: directly read 32-bit unsigned depth values. */
  276.       /* Compute shift value to scale depth values up to 32-bit uints. */
  277.       GLuint shift = 0;
  278.       GLuint max = MAX_DEPTH;
  279.       while ((max&0x80000000)==0) {
  280.          max = max << 1;
  281.          shift++;
  282.       }
  283.       for (j=0;j<height;j++,y++) {
  284.          GLuint *dst = (GLuint *) pixels + start + j * k;
  285.          (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
  286.          for (i=0;i<width;i++) {
  287.             dst[i] = dst[i] << shift;
  288.          }
  289.       }
  290.    }
  291.    else {
  292.       /* General case (slow) */
  293.       for (j=0;j<height;j++,y++) {
  294.          GLfloat depth[MAX_WIDTH];
  295.  
  296.          (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, x, y, depth );
  297.  
  298.          if (bias_or_scale) {
  299.             for (i=0;i<width;i++) {
  300.                GLfloat d;
  301.                d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
  302.                depth[i] = CLAMP( d, 0.0, 1.0 );
  303.             }
  304.          }
  305.  
  306.          switch (type) {
  307.             case GL_UNSIGNED_BYTE:
  308.                {
  309.                   GLubyte *dst = (GLubyte *) pixels + start + j * k;
  310.                   for (i=0;i<width;i++) {
  311.                      *dst++ = FLOAT_TO_UBYTE( depth[i] );
  312.                   }
  313.                }
  314.                break;
  315.             case GL_BYTE:
  316.                {
  317.                   GLbyte *dst = (GLbyte *) pixels + start + j * k;
  318.                   for (i=0;i<width;i++) {
  319.                      *dst++ = FLOAT_TO_BYTE( depth[i] );
  320.                   }
  321.                }
  322.                break;
  323.             case GL_UNSIGNED_SHORT:
  324.                {
  325.                   GLushort *dst = (GLushort *) pixels + start + j * k;
  326.                   for (i=0;i<width;i++) {
  327.                      *dst++ = FLOAT_TO_USHORT( depth[i] );
  328.                   }
  329.                   if (ctx->Pack.SwapBytes) {
  330.                      gl_swap2( (GLushort *) pixels + start + j * k, width );
  331.                   }
  332.                }
  333.                break;
  334.             case GL_SHORT:
  335.                {
  336.                   GLshort *dst = (GLshort *) pixels + start + j * k;
  337.                   for (i=0;i<width;i++) {
  338.                      *dst++ = FLOAT_TO_SHORT( depth[i] );
  339.                   }
  340.                   if (ctx->Pack.SwapBytes) {
  341.                      gl_swap2( (GLushort *) pixels + start + j * k, width );
  342.                   }
  343.                }
  344.                break;
  345.             case GL_UNSIGNED_INT:
  346.                {
  347.                   GLuint *dst = (GLuint *) pixels + start + j * k;
  348.                   for (i=0;i<width;i++) {
  349.                      *dst++ = FLOAT_TO_UINT( depth[i] );
  350.                   }
  351.                   if (ctx->Pack.SwapBytes) {
  352.                      gl_swap4( (GLuint *) pixels + start + j * k, width );
  353.                   }
  354.                }
  355.                break;
  356.             case GL_INT:
  357.                {
  358.                   GLint *dst = (GLint *) pixels + start + j * k;
  359.                   for (i=0;i<width;i++) {
  360.                      *dst++ = FLOAT_TO_INT( depth[i] );
  361.                   }
  362.                   if (ctx->Pack.SwapBytes) {
  363.                      gl_swap4( (GLuint *) pixels + start + j * k, width );
  364.                   }
  365.                }
  366.                break;
  367.             case GL_FLOAT:
  368.                {
  369.                   GLfloat *dst = (GLfloat *) pixels + start + j * k;
  370.                   for (i=0;i<width;i++) {
  371.                      *dst++ = depth[i];
  372.                   }
  373.                   if (ctx->Pack.SwapBytes) {
  374.                      gl_swap4( (GLuint *) pixels + start + j * k, width );
  375.                   }
  376.                }
  377.                break;
  378.             default:
  379.                gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  380.          }
  381.       }
  382.    }
  383. }
  384.  
  385.  
  386.  
  387.  
  388. static void read_stencil_pixels( GLcontext *ctx,
  389.                                  GLint x, GLint y,
  390.                  GLsizei width, GLsizei height,
  391.                  GLenum type, GLvoid *pixels )
  392. {
  393.    GLint i, j;
  394.    GLuint a, s, k, l, start;
  395.    GLboolean shift_or_offset;
  396.  
  397.    if (ctx->Visual->StencilBits<=0) {
  398.       /* No stencil buffer */
  399.       gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
  400.       return;
  401.    }
  402.  
  403.    shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
  404.  
  405.    /* Size of each component */
  406.    s = gl_sizeof_type( type );
  407.    if (s<=0) {
  408.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  409.       return;
  410.    }
  411.  
  412.    /* Compute packing parameters */
  413.    a = ctx->Pack.Alignment;
  414.    if (ctx->Pack.RowLength>0) {
  415.       l = ctx->Pack.RowLength;
  416.    }
  417.    else {
  418.       l = width;
  419.    }
  420.    /* k = offset between rows in components */
  421.    if (s>=a) {
  422.       k = l;
  423.    }
  424.    else {
  425.       k = a/s * CEILING( s*l, a );
  426.    }
  427.  
  428.    /* offset to first component returned */
  429.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
  430.  
  431.    /* process image row by row */
  432.    for (j=0;j<height;j++,y++) {
  433.       GLubyte stencil[MAX_WIDTH];
  434.  
  435.       gl_read_stencil_span( ctx, width, x, y, stencil );
  436.  
  437.       if (shift_or_offset) {
  438.      GLuint s;
  439.      if (ctx->Pixel.IndexShift<0) {
  440.         /* right shift */
  441.         s = -ctx->Pixel.IndexShift;
  442.         for (i=0;i<width;i++) {
  443.            stencil[i] = (stencil[i] >> s) + ctx->Pixel.IndexOffset;
  444.         }
  445.      }
  446.      else {
  447.         /* left shift */
  448.         s = ctx->Pixel.IndexShift;
  449.         for (i=0;i<width;i++) {
  450.            stencil[i] = (stencil[i] << s) + ctx->Pixel.IndexOffset;
  451.         }
  452.      }
  453.       }
  454.  
  455.       if (ctx->Pixel.MapStencilFlag) {
  456.      for (i=0;i<width;i++) {
  457.         stencil[i] = ctx->Pixel.MapStoS[ stencil[i] ];
  458.      }
  459.       }
  460.  
  461.       switch (type) {
  462.      case GL_UNSIGNED_BYTE:
  463.         {
  464.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  465.            MEMCPY( dst, stencil, width );
  466.         }
  467.         break;
  468.      case GL_BYTE:
  469.         {
  470.            GLbyte *dst = (GLbyte  *) pixels + start + j * k;
  471.            MEMCPY( dst, stencil, width );
  472.         }
  473.         break;
  474.      case GL_UNSIGNED_SHORT:
  475.         {
  476.            GLushort *dst = (GLushort *) pixels + start + j * k;
  477.            for (i=0;i<width;i++) {
  478.           *dst++ = (GLushort) stencil[i];
  479.            }
  480.            if (ctx->Pack.SwapBytes) {
  481.           gl_swap2( (GLushort *) pixels + start +j * k, width );
  482.            }
  483.         }
  484.         break;
  485.      case GL_SHORT:
  486.         {
  487.            GLshort *dst = (GLshort *) pixels + start + j * k;
  488.            for (i=0;i<width;i++) {
  489.           *dst++ = (GLshort) stencil[i];
  490.            }
  491.            if (ctx->Pack.SwapBytes) {
  492.           gl_swap2( (GLushort *) pixels + start +j * k, width );
  493.            }
  494.         }
  495.         break;
  496.      case GL_UNSIGNED_INT:
  497.         {
  498.            GLuint *dst = (GLuint *) pixels + start + j * k;
  499.            for (i=0;i<width;i++) {
  500.           *dst++ = (GLuint) stencil[i];
  501.            }
  502.            if (ctx->Pack.SwapBytes) {
  503.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  504.            }
  505.         }
  506.         break;
  507.      case GL_INT:
  508.         {
  509.            GLint *dst = (GLint *) pixels + start + j * k;
  510.            for (i=0;i<width;i++) {
  511.           *dst++ = (GLint) stencil[i];
  512.            }
  513.            if (ctx->Pack.SwapBytes) {
  514.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  515.            }
  516.         }
  517.         break;
  518.      case GL_FLOAT:
  519.         {
  520.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  521.            for (i=0;i<width;i++) {
  522.           *dst++ = (GLfloat) stencil[i];
  523.            }
  524.            if (ctx->Pack.SwapBytes) {
  525.           gl_swap4( (GLuint *) pixels + start +j * k, width );
  526.            }
  527.         }
  528.         break;
  529.          default:
  530.             gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  531.       }
  532.    }
  533. }
  534.  
  535.  
  536.  
  537. /*
  538.  * Test if scaling or biasing of colors is needed.
  539.  */
  540. static GLboolean scale_or_bias_rgba( GLcontext *ctx )
  541. {
  542.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  543.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  544.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  545.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  546.       return GL_TRUE;
  547.    }
  548.    else {
  549.       return GL_FALSE;
  550.    }
  551. }
  552.  
  553.  
  554.  
  555. /*
  556.  * Apply scale and bias factors to an array of RGBA pixels.
  557.  */
  558. static void scale_and_bias_rgba( GLcontext *ctx,
  559.                                  GLint n,
  560.                  GLfloat red[], GLfloat green[],
  561.                  GLfloat blue[], GLfloat alpha[] )
  562. {
  563.    register GLint i;
  564.    register GLfloat r, g, b, a;
  565.  
  566.    for (i=0;i<n;i++) {
  567.       r = red[i]   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  568.       g = green[i] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  569.       b = blue[i]  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  570.       a = alpha[i] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  571.       red[i]   = CLAMP( r, 0.0F, 1.0F );
  572.       green[i] = CLAMP( g, 0.0F, 1.0F );
  573.       blue[i]  = CLAMP( b, 0.0F, 1.0F );
  574.       alpha[i] = CLAMP( a, 0.0F, 1.0F );
  575.    }
  576. }
  577.  
  578.  
  579.  
  580. /*
  581.  * Apply pixel mapping to an array of RGBA pixels.
  582.  */
  583. static void map_rgba( GLcontext *ctx,
  584.                       GLint n,
  585.               GLfloat red[], GLfloat green[],
  586.               GLfloat blue[], GLfloat alpha[] )
  587. {
  588.    GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
  589.    GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
  590.    GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
  591.    GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
  592.    GLint i;
  593.  
  594.    for (i=0;i<n;i++) {
  595.       red[i]   = ctx->Pixel.MapRtoR[ (GLint) (red[i]   * rscale) ];
  596.       green[i] = ctx->Pixel.MapGtoG[ (GLint) (green[i] * gscale) ];
  597.       blue[i]  = ctx->Pixel.MapBtoB[ (GLint) (blue[i]  * bscale) ];
  598.       alpha[i] = ctx->Pixel.MapAtoA[ (GLint) (alpha[i] * ascale) ];
  599.    }
  600. }
  601.  
  602.  
  603.  
  604.  
  605. /*
  606.  * Read R, G, B, A, RGB, L, or LA pixels.
  607.  */
  608. static void read_color_pixels( GLcontext *ctx,
  609.                                GLint x, GLint y,
  610.                    GLsizei width, GLsizei height,
  611.                    GLenum format, GLenum type, GLvoid *pixels )
  612. {
  613.    GLint i, j, n, a, s, l, k;
  614.    GLboolean scale_or_bias;
  615.    DEFARRAY(GLfloat, red, MAX_WIDTH);
  616.    DEFARRAY(GLfloat, green, MAX_WIDTH);
  617.    DEFARRAY(GLfloat, blue, MAX_WIDTH);
  618.    DEFARRAY(GLfloat, alpha, MAX_WIDTH);
  619.    DEFARRAY(GLfloat, luminance, MAX_WIDTH);
  620.    GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
  621.    GLuint start;
  622.  
  623.    scale_or_bias = scale_or_bias_rgba( ctx );
  624.  
  625.    /* Determine how many / which components to return */
  626.    r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
  627.    switch (format) {
  628.       case GL_RED:                r_flag = GL_TRUE;  n = 1;  break;
  629.       case GL_GREEN:                g_flag = GL_TRUE;  n = 1;  break;
  630.       case GL_BLUE:                b_flag = GL_TRUE;  n = 1;  break;
  631.       case GL_ALPHA:                a_flag = GL_TRUE;  n = 1;  break;
  632.       case GL_LUMINANCE:            l_flag = GL_TRUE;  n = 1;  break;
  633.       case GL_LUMINANCE_ALPHA:           l_flag = a_flag = GL_TRUE;  n = 2;  break;
  634.       case GL_RGB:          r_flag = g_flag = b_flag = GL_TRUE;  n = 3;  break;
  635.       case GL_RGBA:  r_flag = g_flag = b_flag = a_flag = GL_TRUE;  n = 4;  break;
  636.       default:
  637.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  638.          UNDEFARRAY( red );
  639.          UNDEFARRAY( green );
  640.          UNDEFARRAY( blue );
  641.          UNDEFARRAY( alpha );
  642.          UNDEFARRAY( luminance );
  643.          return;
  644.    }
  645.  
  646.    /* Size of each component */
  647.    s = gl_sizeof_type( type );
  648.    if (s<=0) {
  649.       gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  650.       UNDEFARRAY( red );
  651.       UNDEFARRAY( green );
  652.       UNDEFARRAY( blue );
  653.       UNDEFARRAY( alpha );
  654.       UNDEFARRAY( luminance );
  655.       return;
  656.    }
  657.  
  658.    /* Compute packing parameters */
  659.    a = ctx->Pack.Alignment;
  660.    if (ctx->Pack.RowLength>0) {
  661.       l = ctx->Pack.RowLength;
  662.    }
  663.    else {
  664.       l = width;
  665.    }
  666.    /* k = offset between rows in components */
  667.    if (s>=a) {
  668.       k = n * l;
  669.    }
  670.    else {
  671.       k = a/s * CEILING( s*n*l, a );
  672.    }
  673.  
  674.    /* offset to first component returned */
  675.    start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels * n;
  676.  
  677.    /* process image row by row */
  678.    for (j=0;j<height;j++,y++) {
  679.  
  680.       /*
  681.        * Read the pixels from frame buffer
  682.        */
  683.       if (ctx->Visual->RGBAflag) {
  684.          DEFARRAY(GLubyte, r, MAX_WIDTH);
  685.          DEFARRAY(GLubyte, g, MAX_WIDTH);
  686.          DEFARRAY(GLubyte, b, MAX_WIDTH);
  687.          DEFARRAY(GLubyte, a, MAX_WIDTH);
  688.      GLfloat rscale = 1.0F * ctx->Visual->InvRedScale;
  689.      GLfloat gscale = 1.0F * ctx->Visual->InvGreenScale;
  690.      GLfloat bscale = 1.0F * ctx->Visual->InvBlueScale;
  691.      GLfloat ascale = 1.0F * ctx->Visual->InvAlphaScale;
  692.  
  693.      /* read colors and convert to floats */
  694.      (*ctx->Driver.ReadColorSpan)( ctx, width, x, y, r, g, b, a );
  695.          if (ctx->RasterMask & ALPHABUF_BIT) {
  696.             gl_read_alpha_span( ctx, width, x, y, a );
  697.          }
  698.      for (i=0;i<width;i++) {
  699.         red[i]   = r[i] * rscale;
  700.         green[i] = g[i] * gscale;
  701.         blue[i]  = b[i] * bscale;
  702.         alpha[i] = a[i] * ascale;
  703.      }
  704.  
  705.      if (scale_or_bias) {
  706.         scale_and_bias_rgba( ctx, width, red, green, blue, alpha );
  707.      }
  708.      if (ctx->Pixel.MapColorFlag) {
  709.         map_rgba( ctx, width, red, green, blue, alpha );
  710.      }
  711.          UNDEFARRAY(r);
  712.          UNDEFARRAY(g);
  713.          UNDEFARRAY(b);
  714.          UNDEFARRAY(a);
  715.       }
  716.       else {
  717.      /* convert CI values to RGBA */
  718.      GLuint index[MAX_WIDTH];
  719.      (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, index );
  720.  
  721.      if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
  722.         GLuint s;
  723.         if (ctx->Pixel.IndexShift<0) {
  724.            /* right shift */
  725.            s = -ctx->Pixel.IndexShift;
  726.            for (i=0;i<width;i++) {
  727.           index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
  728.            }
  729.         }
  730.         else {
  731.            /* left shift */
  732.            s = ctx->Pixel.IndexShift;
  733.            for (i=0;i<width;i++) {
  734.           index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
  735.            }
  736.         }
  737.      }
  738.  
  739.      for (i=0;i<width;i++) {
  740.         red[i]   = ctx->Pixel.MapItoR[ index[i] ];
  741.         green[i] = ctx->Pixel.MapItoG[ index[i] ];
  742.         blue[i]  = ctx->Pixel.MapItoB[ index[i] ];
  743.         alpha[i] = ctx->Pixel.MapItoA[ index[i] ];
  744.      }
  745.       }
  746.  
  747.       if (l_flag) {
  748.          for (i=0;i<width;i++) {
  749.             GLfloat sum = red[i] + green[i] + blue[i];
  750.             luminance[i] = CLAMP( sum, 0.0F, 1.0F );
  751.          }
  752.       }
  753.  
  754.       /*
  755.        * Pack/transfer/store the pixels
  756.        */
  757.  
  758.       switch (type) {
  759.      case GL_UNSIGNED_BYTE:
  760.         {
  761.            GLubyte *dst = (GLubyte *) pixels + start + j * k;
  762.            for (i=0;i<width;i++) {
  763.           if (r_flag)  *dst++ = FLOAT_TO_UBYTE( red[i] );
  764.           if (g_flag)  *dst++ = FLOAT_TO_UBYTE( green[i] );
  765.           if (b_flag)  *dst++ = FLOAT_TO_UBYTE( blue[i] );
  766.           if (l_flag)  *dst++ = FLOAT_TO_UBYTE( luminance[i] );
  767.           if (a_flag)  *dst++ = FLOAT_TO_UBYTE( alpha[i] );
  768.            }
  769.         }
  770.         break;
  771.      case GL_BYTE:
  772.         {
  773.            GLbyte *dst = (GLbyte *) pixels + start + j * k;
  774.            for (i=0;i<width;i++) {
  775.           if (r_flag)  *dst++ = FLOAT_TO_BYTE( red[i] );
  776.           if (g_flag)  *dst++ = FLOAT_TO_BYTE( green[i] );
  777.           if (b_flag)  *dst++ = FLOAT_TO_BYTE( blue[i] );
  778.           if (l_flag)  *dst++ = FLOAT_TO_BYTE( luminance[i] );
  779.           if (a_flag)  *dst++ = FLOAT_TO_BYTE( alpha[i] );
  780.            }
  781.         }
  782.         break;
  783.      case GL_UNSIGNED_SHORT:
  784.         {
  785.            GLushort *dst = (GLushort *) pixels + start + j * k;
  786.            for (i=0;i<width;i++) {
  787.           if (r_flag)  *dst++ = FLOAT_TO_USHORT( red[i] );
  788.           if (g_flag)  *dst++ = FLOAT_TO_USHORT( green[i] );
  789.           if (b_flag)  *dst++ = FLOAT_TO_USHORT( blue[i] );
  790.           if (l_flag)  *dst++ = FLOAT_TO_USHORT( luminance[i] );
  791.           if (a_flag)  *dst++ = FLOAT_TO_USHORT( alpha[i] );
  792.            }
  793.         }
  794.         if (ctx->Pack.SwapBytes) {
  795.            gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  796.         }
  797.         break;
  798.      case GL_SHORT:
  799.         {
  800.            GLshort *dst = (GLshort *) pixels + start + j * k;
  801.            for (i=0;i<width;i++) {
  802.           if (r_flag)  *dst++ = FLOAT_TO_SHORT( red[i] );
  803.           if (g_flag)  *dst++ = FLOAT_TO_SHORT( green[i] );
  804.           if (b_flag)  *dst++ = FLOAT_TO_SHORT( blue[i] );
  805.           if (l_flag)  *dst++ = FLOAT_TO_SHORT( luminance[i] );
  806.           if (a_flag)  *dst++ = FLOAT_TO_SHORT( alpha[i] );
  807.            }
  808.            if (ctx->Pack.SwapBytes) {
  809.           gl_swap2( (GLushort *) pixels + start + j * k, width*n );
  810.            }
  811.         }
  812.         break;
  813.      case GL_UNSIGNED_INT:
  814.         {
  815.            GLuint *dst = (GLuint *) pixels + start + j * k;
  816.            for (i=0;i<width;i++) {
  817.           if (r_flag)  *dst++ = FLOAT_TO_UINT( red[i] );
  818.           if (g_flag)  *dst++ = FLOAT_TO_UINT( green[i] );
  819.           if (b_flag)  *dst++ = FLOAT_TO_UINT( blue[i] );
  820.           if (l_flag)  *dst++ = FLOAT_TO_UINT( luminance[i] );
  821.           if (a_flag)  *dst++ = FLOAT_TO_UINT( alpha[i] );
  822.            }
  823.            if (ctx->Pack.SwapBytes) {
  824.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  825.            }
  826.         }
  827.         break;
  828.      case GL_INT:
  829.         {
  830.            GLint *dst = (GLint *) pixels + start + j * k;
  831.            for (i=0;i<width;i++) {
  832.           if (r_flag)  *dst++ = FLOAT_TO_INT( red[i] );
  833.           if (g_flag)  *dst++ = FLOAT_TO_INT( green[i] );
  834.           if (b_flag)  *dst++ = FLOAT_TO_INT( blue[i] );
  835.           if (l_flag)  *dst++ = FLOAT_TO_INT( luminance[i] );
  836.           if (a_flag)  *dst++ = FLOAT_TO_INT( alpha[i] );
  837.            }
  838.            if (ctx->Pack.SwapBytes) {
  839.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  840.            }
  841.         }
  842.         break;
  843.      case GL_FLOAT:
  844.         {
  845.            GLfloat *dst = (GLfloat *) pixels + start + j * k;
  846.            for (i=0;i<width;i++) {
  847.           if (r_flag)  *dst++ = red[i];
  848.           if (g_flag)  *dst++ = green[i];
  849.           if (b_flag)  *dst++ = blue[i];
  850.           if (l_flag)  *dst++ = luminance[i];
  851.           if (a_flag)  *dst++ = alpha[i];
  852.            }
  853.            if (ctx->Pack.SwapBytes) {
  854.           gl_swap4( (GLuint *) pixels + start + j * k, width*n );
  855.            }
  856.         }
  857.         break;
  858.          default:
  859.             gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
  860.       }
  861.    }
  862.    UNDEFARRAY( red );
  863.    UNDEFARRAY( green );
  864.    UNDEFARRAY( blue );
  865.    UNDEFARRAY( alpha );
  866.    UNDEFARRAY( luminance );
  867. }
  868.  
  869.  
  870.  
  871. void gl_ReadPixels( GLcontext *ctx,
  872.                     GLint x, GLint y, GLsizei width, GLsizei height,
  873.             GLenum format, GLenum type, GLvoid *pixels )
  874. {
  875.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  876.  
  877.    switch (format) {
  878.       case GL_COLOR_INDEX:
  879.          read_index_pixels( ctx, x, y, width, height, type, pixels );
  880.      break;
  881.       case GL_STENCIL_INDEX:
  882.      read_stencil_pixels( ctx, x, y, width, height, type, pixels );
  883.          break;
  884.       case GL_DEPTH_COMPONENT:
  885.      read_depth_pixels( ctx, x, y, width, height, type, pixels );
  886.      break;
  887.       case GL_RED:
  888.       case GL_GREEN:
  889.       case GL_BLUE:
  890.       case GL_ALPHA:
  891.       case GL_RGB:
  892.       case GL_LUMINANCE:
  893.       case GL_LUMINANCE_ALPHA:
  894.       case GL_RGBA:
  895.      read_color_pixels( ctx, x, y, width, height, format, type, pixels );
  896.      break;
  897.       default:
  898.      gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
  899.    }
  900.  
  901.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  902. }
  903.